Lås op for kraften i React Suspense for forbedret datahentning, opdeling af kode og en mere flydende brugeroplevelse. Lær hvordan du implementerer Suspense med praktiske eksempler og bedste praksisser.
React Suspense: En omfattende guide til datahentning og opdeling af kode
React Suspense er en kraftfuld funktion, der blev introduceret i React 16.6, og som giver dig mulighed for at "suspende" komponentrendering, mens du venter på noget, f.eks. at data indlæses, eller kode downloades. Dette giver en deklarativ måde at håndtere indlæsningstilstande og forbedre brugeroplevelsen ved elegant at håndtere asynkrone operationer. Denne guide fører dig gennem begreberne Suspense, dets brugsscenarier og praktiske eksempler på, hvordan du implementerer det i dine React-applikationer.
Hvad er React Suspense?
Suspense er en React-komponent, der ombryder andre komponenter og giver dig mulighed for at vise en fallback-UI (f.eks. en indlæsningsspinner), mens disse komponenter venter på, at et promise løses. Dette promise kan være relateret til:
- Datahentning: Venter på, at data hentes fra en API.
- Opdeling af kode: Venter på, at JavaScript-moduler downloades og parses.
Før Suspense involverede håndtering af indlæsningstilstande ofte kompleks betinget rendering og manuel håndtering af asynkrone operationer. Suspense forenkler dette ved at give en deklarativ tilgang, der gør din kode renere og mere vedligeholdelsesvenlig.
Nøglekoncepter
- Suspense-komponent: Selve
<Suspense>-komponenten. Den accepterer enfallbackprop, som specificerer den UI, der skal vises, mens de omviklede komponenter suspenderes. - React.lazy(): En funktion, der muliggør opdeling af kode ved dynamisk at importere komponenter. Den returnerer et
Promise, der løses, når komponenten er indlæst. - Promise-integration: Suspense integreres problemfrit med Promises. Når en komponent forsøger at gengive data fra et Promise, der endnu ikke er løst, "suspenderes" den og viser fallback-UI'en.
Brugsscenarier
1. Datahentning med Suspense
Et af de primære brugsscenarier for Suspense er at håndtere datahentning. I stedet for manuelt at håndtere indlæsningstilstande med betinget rendering, kan du bruge Suspense til deklarativt at vise en indlæsningsindikator, mens du venter på, at data ankommer.
Eksempel: Hentning af brugerdata fra en API
Lad os sige, at du har en komponent, der viser brugerdata, der er hentet fra en API. Uden Suspense kan du have kode som denne:
import React, { useState, useEffect } from 'react';
function UserProfile() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch('https://api.example.com/users/123');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err);
} finally {
setIsLoading(false);
}
}
fetchData();
}, []);
if (isLoading) {
return <p>Loading user data...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
if (!user) {
return <p>No user data available.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
export default UserProfile;
Denne kode fungerer, men den involverer håndtering af flere tilstandsvariabler (isLoading, error, user) og betinget renderingslogik. Med Suspense kan du forenkle dette ved hjælp af et datahentningsbibliotek som SWR eller TanStack Query (tidligere React Query), som er designet til at fungere problemfrit med Suspense.
Her er, hvordan du kan bruge SWR med Suspense:
import React from 'react';
import useSWR from 'swr';
// A simple fetcher function
const fetcher = (...args) => fetch(...args).then(res => res.json());
function UserProfile() {
const { data: user, error } = useSWR('/api/users/123', fetcher, { suspense: true });
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
function App() {
return (
<Suspense fallback={<p>Loading user data...</p>}>
<UserProfile />
</Suspense>
);
}
export default App;
I dette eksempel:
- Vi bruger
useSWRtil at hente brugerdataene. Indstillingensuspense: truefortæller SWR at kaste et Promise, hvis dataene endnu ikke er tilgængelige. UserProfile-komponenten behøver ikke at håndtere indlæsnings- eller fejltilstande eksplicit. Den gengiver simpelthen brugerdataene, når de er tilgængelige.<Suspense>-komponenten fanger det Promise, der kastes af SWR, og viser fallback-UI'en (<p>Loading user data...</p>), mens dataene hentes.
Denne tilgang forenkler din komponentlogik og gør det lettere at ræsonnere om datahentning.
Globale overvejelser for datahentning:
Når du bygger applikationer til et globalt publikum, skal du overveje følgende:
- Netværksforsinkelse: Brugere i forskellige geografiske områder kan opleve varierende netværksforsinkelse. Suspense kan hjælpe med at give en bedre brugeroplevelse ved at vise indlæsningsindikatorer, mens data hentes fra fjerne servere. Overvej at bruge et Content Delivery Network (CDN) til at cache dine data tættere på dine brugere.
- Datalokalisering: Sørg for, at din API understøtter datalokalisering, så du kan servere data på brugerens foretrukne sprog og format.
- API-tilgængelighed: Overvåg tilgængeligheden og ydeevnen af dine API'er fra forskellige regioner for at sikre en ensartet brugeroplevelse.
2. Opdeling af kode med React.lazy() og Suspense
Opdeling af kode er en teknik til at opdele din applikation i mindre bidder, som kan indlæses efter behov. Dette kan forbedre den indledende indlæsningstid for din applikation betydeligt, især for store og komplekse projekter.
React leverer funktionen React.lazy() til opdeling af kodekomponenter. Når det bruges med Suspense, giver det dig mulighed for at vise en fallback-UI, mens du venter på, at komponenten downloades og parses.
Eksempel: Lazy loading af en komponent
import React, { Suspense, lazy } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<p>Loading...</p>}>
<OtherComponent />
</Suspense>
</div>
);
}
export default MyComponent;
I dette eksempel:
- Vi bruger
React.lazy()til dynamisk at importereOtherComponent. Dette returnerer et Promise, der løses, når komponenten er indlæst. - Vi ombryder
<OtherComponent />med<Suspense>og angiver enfallbackprop. - Mens
OtherComponentindlæses, vises fallback-UI'en (<p>Loading...</p>). Når komponenten er indlæst, erstatter den fallback-UI'en.
Fordele ved opdeling af kode:
- Forbedret indledende indlæsningstid: Ved kun at indlæse den nødvendige kode til den indledende visning, kan du reducere den tid, det tager for din applikation at blive interaktiv.
- Reduceret bundle-størrelse: Opdeling af kode kan hjælpe med at reducere den samlede størrelse af din applikations JavaScript-bundle, hvilket kan forbedre ydeevnen, især på forbindelser med lav båndbredde.
- Bedre brugeroplevelse: Ved at give en hurtigere indledende indlæsning og kun indlæse kode efter behov, kan du skabe en mere flydende og responsiv brugeroplevelse.
Avancerede teknikker til opdeling af kode:
- Rutebaseret opdeling af kode: Opdel din applikation baseret på ruter, så hver rute kun indlæser den kode, den har brug for. Dette kan nemt opnås med biblioteker som React Router.
- Komponentbaseret opdeling af kode: Opdel individuelle komponenter i separate bidder, især for store eller sjældent brugte komponenter.
- Dynamiske importer: Brug dynamiske importer i dine komponenter til at indlæse kode efter behov baseret på brugerinteraktioner eller andre forhold.
3. Concurrent Mode og Suspense
Suspense er en nøgleingrediens i Reacts Concurrent Mode, et sæt nye funktioner, der gør det muligt for React at arbejde på flere opgaver samtidigt. Concurrent Mode giver React mulighed for at prioritere vigtige opdateringer, afbryde langvarige opgaver og forbedre responsiviteten i din applikation.
Med Concurrent Mode og Suspense kan React:
- Starte gengivelse af komponenter, før alle data er tilgængelige: React kan starte gengivelse af en komponent, selvom nogle af dens dataafhængigheder stadig hentes. Dette giver React mulighed for at vise en delvis UI hurtigere, hvilket forbedrer den opfattede ydeevne af din applikation.
- Afbryde og genoptage gengivelse: Hvis en opdatering med højere prioritet kommer ind, mens React gengiver en komponent, kan den afbryde gengivelsesprocessen, håndtere opdateringen med højere prioritet og derefter genoptage gengivelsen af komponenten senere.
- Undgå at blokere hovedtråden: Concurrent Mode giver React mulighed for at udføre langvarige opgaver uden at blokere hovedtråden, hvilket kan forhindre, at UI'en bliver ikke-responsiv.
For at aktivere Concurrent Mode kan du bruge createRoot API'en i React 18:
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
const container = document.getElementById('root');
const root = createRoot(container); // Create a root.
root.render(<App />);
Bedste praksisser for brug af Suspense
- Brug et datahentningsbibliotek: Overvej at bruge et datahentningsbibliotek som SWR eller TanStack Query, som er designet til at fungere problemfrit med Suspense. Disse biblioteker tilbyder funktioner som caching, automatiske genforsøg og fejlhåndtering, som kan forenkle din datahentningslogik.
- Angiv meningsfuld fallback-UI: Fallback-UI'en skal give en klar indikation af, at noget indlæses. Brug spinnere, statuslinjer eller skeletindlæsere til at skabe en visuelt tiltalende og informativ indlæsningsoplevelse.
- Håndter fejl elegant: Brug Error Boundaries til at fange fejl, der opstår under gengivelse. Dette kan forhindre, at hele din applikation crasher og give en bedre brugeroplevelse.
- Optimer opdeling af kode: Brug opdeling af kode strategisk for at reducere den indledende indlæsningstid for din applikation. Identificer store eller sjældent brugte komponenter, og opdel dem i separate bidder.
- Test din Suspense-implementering: Test din Suspense-implementering grundigt for at sikre, at den fungerer korrekt, og at din applikation håndterer indlæsningstilstande og fejl elegant.
Fejlhåndtering med Error Boundaries
Mens Suspense håndterer *indlæsningstilstanden*, håndterer Error Boundaries *fejltilstanden* under gengivelse. Error Boundaries er React-komponenter, der fanger JavaScript-fejl hvor som helst i deres underordnede komponenttræ, logger disse fejl og viser en fallback-UI i stedet for at crashe hele komponenttræet.
Her er et grundlæggende eksempel på en Error Boundary:
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
For at bruge Error Boundary skal du ombryde den omkring den komponent, der muligvis kaster en fejl:
import ErrorBoundary from './ErrorBoundary';
import MyComponent from './MyComponent';
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}
export default App;
Ved at kombinere Suspense og Error Boundaries kan du skabe en robust og modstandsdygtig applikation, der håndterer både indlæsningstilstande og fejl elegant.
Eksempler fra den virkelige verden
Her er et par eksempler fra den virkelige verden på, hvordan Suspense kan bruges til at forbedre brugeroplevelsen:
- E-handelswebsted: Brug Suspense til at vise indlæsningsindikatorer, mens du henter produktoplysninger eller billeder. Dette kan forhindre brugeren i at se en tom side, mens du venter på, at dataene indlæses.
- Social medieplatform: Brug Suspense til lazy loading af kommentarer eller indlæg, mens brugeren ruller ned ad siden. Dette kan forbedre den indledende indlæsningstid for siden og reducere mængden af data, der skal downloades.
- Dashboard-applikation: Brug Suspense til at vise indlæsningsindikatorer, mens du henter data til diagrammer eller grafer. Dette kan give en mere flydende og responsiv brugeroplevelse.
Eksempel: International e-handelsplatform
Overvej en international e-handelsplatform, der sælger produkter globalt. Platformen kan udnytte Suspense og React.lazy() til at:
- Lazy load af produktbilleder: Brug
React.lazy()til kun at indlæse produktbilleder, når de er synlige i visningsporten. Dette kan reducere den indledende indlæsningstid for produktlistesiden betydeligt. Ombryd hvert lazy-loaded billede med<Suspense fallback={<img src="placeholder.png" alt="Loading..." />}>for at vise et pladsholderbillede, mens det faktiske billede indlæses. - Opdel kode til landespecifikke komponenter: Hvis platformen har landespecifikke komponenter (f.eks. valutaformatering, adresseinputfelter), skal du bruge
React.lazy()til kun at indlæse disse komponenter, når brugeren vælger et bestemt land. - Hent lokaliserede produktbeskrivelser: Brug et datahentningsbibliotek som SWR med Suspense til at hente produktbeskrivelser på brugerens foretrukne sprog. Vis en indlæsningsindikator, mens de lokaliserede beskrivelser hentes.
Konklusion
React Suspense er en kraftfuld funktion, der markant kan forbedre brugeroplevelsen af dine React-applikationer. Ved at give en deklarativ måde at håndtere indlæsningstilstande og opdeling af kode på, forenkler Suspense din kode og gør det lettere at ræsonnere om asynkrone operationer. Uanset om du bygger et lille personligt projekt eller en stor virksomhedsapplikation, kan Suspense hjælpe dig med at skabe en mere flydende, mere responsiv og mere performant brugeroplevelse.
Ved at integrere Suspense med datahentningsbiblioteker og teknikker til opdeling af kode, kan du låse det fulde potentiale i Reacts Concurrent Mode op og skabe virkelig moderne og engagerende webapplikationer. Omfavn Suspense, og løft din React-udvikling til næste niveau.